package com.cy.teducommunitys.com.cy.service.impl;

import ch.qos.logback.core.net.SyslogOutputStream;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cy.teducommunitys.com.common.annotation.RequiredLog;
import com.cy.teducommunitys.com.common.cellphone.TelePhone;
import com.cy.teducommunitys.com.common.vo.JsonResult;
import com.cy.teducommunitys.com.common.vo.UserForManagerVo;
import com.cy.teducommunitys.com.cy.entity.User;
import com.cy.teducommunitys.com.cy.mapper.UserMapper;
import com.cy.teducommunitys.com.cy.service.IUserService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cy.teducommunitys.com.cy.service.serviceexception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.UUID;

/**
 * <p>
 * 用户详细信息表 服务实现类
 * </p>
 *
 * @author mdzz
 * @since 2019-07-19
 */
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
    @SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
    @Autowired
    private UserMapper userMapper;

    /**
     * page中封装了页码，和页中数据的数量
     * state是根据用户的查询来生成对应的查询条件，null为没有查询条件查询全部
     * */
    @RequiredLog("分页查询")
    @Override
    public IPage<UserForManagerVo> selectUserPage(Page<UserForManagerVo> page, String state) {
        // 不进行 count sql 优化，解决 MP 无法自动优化 SQL 问题，这时候你需要自己查询 count 部分
        // page.setOptimizeCountSql(false);
        // 当 total 为小于 0 或者设置 setSearchCount(false) 分页插件不会进行 count 查询
        // 要点!! 分页返回的对象与传入的对象是同一个
        IPage<UserForManagerVo> userForManagerVoIPage;
        try {
            userForManagerVoIPage = userMapper.selectPageVo(page, state);
        } catch (Exception e) {
            throw new ServiceException("服务器有问题");
        }
        if (userForManagerVoIPage.getRecords()==null)
            throw new ServiceException("没有你所要要求的检索");
        return userForManagerVoIPage;
    }
    /**通过接收到的手机号来产生验证码并返回*/
    @RequiredLog("手机验证码")
    @Override
    public String getCode(String phone){
       return TelePhone.getCode(phone);
    }

    /**用户的禁用启用*/
    @Override
    public int validById(User user) {
        //1.合法性验证
        if(user.getUserId()==null||user.getUserId()<=0)
            throw new ServiceException("参数不合法,id="+user.getUserId());
        if(user.getValid()!=1&&user.getValid()!=0)
            throw new ServiceException("参数不合法,valie="+user.getValid());
        User userOperater=(User) SecurityUtils.getSubject().getPrincipal();
//        user.setModifiedUser(userOperater.getUserName());
        //2.执行禁用或启用操作
        int rows=0;
        try{
            rows=userMapper.update(user,new UpdateWrapper<User>().eq("userId",user.getUserId()));
        }catch(Throwable e){
            e.printStackTrace();
            //报警,给维护人员发短信
            throw new ServiceException("底层正在维护");
        }
        //3.判定结果,并返回
        if(rows==0)
            throw new ServiceException("此记录可能已经不存在");
        return rows;
    }
    /**修改用户密码*/
    @Override
    public int updatePassword(String password, String newPassword, String cfgPassword) {
        //1.判定新密码与密码确认是否相同
        if(StringUtils.isEmpty(newPassword))
            throw new IllegalArgumentException("新密码不能为空");
        if(StringUtils.isEmpty(cfgPassword))
            throw new IllegalArgumentException("确认密码不能为空");
        if(!newPassword.equals(cfgPassword))
            throw new IllegalArgumentException("两次输入的密码不相等");
        //2.判定原密码是否正确
        if(StringUtils.isEmpty(password))
            throw new IllegalArgumentException("原密码不能为空");
        //获取登陆用户
        User user=(User) SecurityUtils.getSubject().getPrincipal();
        System.out.println(user.getPassword());
        SimpleHash sh=new SimpleHash("MD5",
                password, user.getSalt(), 1);
        if(!user.getPassword().equals(sh.toHex()))
            throw new IllegalArgumentException("原密码不正确");
        //3.对新密码进行加密
        String salt= UUID.randomUUID().toString();
        sh=new SimpleHash("MD5",newPassword,salt, 1);
        //4.将新密码加密以后的结果更新到数据库
        user.setPassword(sh.toHex());
        user.setSalt(salt);
        user.setModifiedTime(new Date());
        int rows = userMapper.update(user, new UpdateWrapper<User>().eq("userId", user.getUserId()));
        if(rows==0)
            throw new ServiceException("修改失败");
        return rows;
    }
    /***/
    @Override
    public UserForManagerVo findObjectById(Integer userId) {
        log.info(userId.toString());
        UserForManagerVo userMapperObjectById ;
        try {
            userMapperObjectById  = userMapper.findObjectById(userId);
            System.out.println(userMapperObjectById);
        } catch (Exception e) {
            throw new ServiceException("服务器维护中或检查一下网络");
        }
        if (userMapperObjectById==null)
            throw new ServiceException("数据已经不存在");
        return userMapperObjectById;
    }
//    /**网页异步验证用户名是否重复*/
//    @Override
//    public void checkUserName(String name) {
//        if (name==null||name=="")
//            throw new ServiceException("用户名不能为空");
//        List<User> userName = userMapper.selectList(new QueryWrapper<User>().like("userName", name));
//        if (!userName.isEmpty())
//            throw new ServiceException("用户名已存在");
//    }

    /**用与后台管理
     * 对用户信息的更新
     * */
    @RequiredLog("更新用户信息")
    @Override
    public void updateObject(User entity) {

        //1.参数有效性验证
        if(entity==null)
            throw new IllegalArgumentException("保存对象不能为空");
        if(StringUtils.isEmpty(entity.getUserName()))
            throw new IllegalArgumentException("用户名不能为空");
        //更新用户信息
        int row;
        try {
            row  = userMapper.updateById(entity);
        } catch (Exception e) {
            throw new ServiceException("更新失败");
        }
        if (row==0)
            throw new ServiceException("没有要更新的用户");
    }

    /**添加用户数据
     *可用于前端用户的注册
     * */
    @RequiredLog("新增用户")
    @Override
    public void saveObject(User entity) {
        //1.验证数据合法性
        if(entity==null)
            throw new ServiceException("保存对象不能为空");
        if(StringUtils.isEmpty(entity.getUserName()))
            throw new ServiceException("用户名不能为空");
        if(StringUtils.isEmpty(entity.getPassword()))
            throw new ServiceException("密码不能为空");
//        if(entity.getRoleId()==null)
//            throw new ServiceException("至少要为用户分配角色");
        //2.将数据写入数据库
        String salt= UUID.randomUUID().toString();
        entity.setSalt(salt);
        //加密
        SimpleHash sHash=
                new SimpleHash("MD5",//加密算法
                        entity.getPassword(), //没加密的密码
                        salt);//盐值
        entity.setValid(1);
        entity.setRoleId(3);//注册时默认对应的角色
        entity.setPassword(sHash.toHex());
        entity.setCreatedUser(entity.getUserName());
        entity.setCreatedTime(new Date());
        int rows=userMapper.insert(entity);
        if (rows<1)
            throw new ServiceException("新增失败");
    }

    /**删除用户
     * 后台根据选中的id删除
     * */
    @RequiredLog("删除")
    @Override
    public void deleteObject(Integer id) {
        //验证参数
        if (id<1)
            throw new IllegalArgumentException("请选择一个");
        int rows;
        try {
            rows = userMapper.delete(new UpdateWrapper<User>().eq("id", id));
        } catch (Exception e) {
            throw new ServiceException("服务器修复中，稍后再操作！");
        }
        if (rows==0)
            throw new ServiceException("用户不存在删除失败");
    }


    @Override
    public JsonResult checkUserName(String userName) {
        if(userMapper.getUserNameCount(userName)==0)
            return new JsonResult("ok");
        return new JsonResult(new ServiceException("该用户名已被注册！"));
    }

    @Override
    public JsonResult checkMobile(String mobile) {
        if(userMapper.getMobileCount(mobile)==0)
            return new JsonResult("ok");
        return new JsonResult(new ServiceException("该手机号已注册过！"));
    }


}
